﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Drawing;
using filter;
using MathWorks.MATLAB.NET.Arrays;
using MathWorks.MATLAB.NET.Utility;
using System.Net;

namespace CoupleFil
{
    public delegate void Realtimehandler();
    public delegate void Printhandler();
    public delegate void Perviewhandler();
    public delegate void BuildTMhandler();
    public delegate void Markerhandler();

    static class Program
    {  
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            //IPAddress[] ips= Dns.GetHostAddresses(Dns.GetHostName());
            //if (ips[0].ToString() == "10.53.2.245")
                Application.Run(new Form1());
            //else
            //    Application.Exit();
        }
        
        public static event Realtimehandler Updatesomething;
        public static void OnUpdatesomething()
        {
            if (Updatesomething != null)
            Updatesomething();
        }
        
        public static event Printhandler Printsomething;
        public static void OnPrintsomething()
        {
            if (Printsomething != null)
            Printsomething();
        }
        
        public static event Perviewhandler Perviewsomething;
        public static void OnPerviewsomething()
        {
            if (Perviewsomething != null)
            Perviewsomething();
        }

        public static event BuildTMhandler Buildsomething;
        public static void onBiuldsomething()
        {
            if (Buildsomething != null)
                Buildsomething();
        }

        public static event Markerhandler Updatemarker;
        public static void onUpdatemarker()
        {
            if (Updatemarker != null)
                Updatemarker();
        }

        public static double[,] GetMatrix()
        {
            MWNumericArray startFeq = null;
            MWNumericArray stopFeq = null;
            MWNumericArray poleNum = null;
            MWNumericArray La = null;
            MWNumericArray Tzdata = null;
            MWNumericArray TzNum = null;
            MWNumericArray Qdata = null;
            MWNumericArray cpMatrix = null;

            startFeq = fp.StartF;
            stopFeq = fp.StopF;
            poleNum = fp.PoleN;
            La = fp.LaVal;
            Qdata = (MWNumericArray)(fp.Q);
            Tzdata = (MWNumericArray)(fp.Tz);
            TzNum = fp.TzN;

            Filter demoFilter = new Filter();
            cpMatrix = (MWNumericArray)demoFilter.instiong6(startFeq, stopFeq, poleNum, La, Qdata, Tzdata, TzNum);
            double[,] nativeCpMatrix = (double[,])cpMatrix.ToArray(MWArrayComponent.Real);
            return nativeCpMatrix;
        }

        private static double[,] GetMidMatrix()     //7*7阶
        {
            double[,] preMatrix = fp.cpMatrix;
            double[,] midMatrix = new double[preMatrix.GetLength(0) - 2, preMatrix.GetLength(1) - 2];
            for (int i = 0; i < preMatrix.GetLength(0) - 2; i++)
            {
                for (int j = 0; j < preMatrix.GetLength(1) - 2; j++)
                {
                    midMatrix[i, j] = preMatrix[i + 1, j + 1];
                }
            }
            return midMatrix;
        }

        private static double[,] optimizeMatrix()        //7*7阶
        {
            MWLogicalArray structMatrix = null;
            MWNumericArray optMatrix = null;
            MWNumericArray poleNum = null;
            MWNumericArray resultMatrix = null;

            structMatrix = new MWLogicalArray(fp.topologyMatrix);
            optMatrix = (MWNumericArray)GetMidMatrix();
            poleNum = fp.PoleN;

            Filter demoFilter = new Filter();
            resultMatrix = (MWNumericArray)demoFilter.optimizeMx(optMatrix, poleNum, structMatrix);
            double[,] nativeMatrix = (double[,])resultMatrix.ToArray(MWArrayComponent.Real);
            return nativeMatrix;
        }

        public static void updatecpMatrix()
        {
            double[,] inputMatrix = optimizeMatrix();
            double[,] outputMatrix = fp.cpMatrix;
            int m = inputMatrix.GetLength(0);
            int n = inputMatrix.GetLength(1);
            for (int i = 0; i < m; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    outputMatrix[i + 1, j + 1] = inputMatrix[i, j];
                }
            }
            fp.cpMatrix = outputMatrix;
        }

        public static double[] GetS11()
        {
            MWStructArray sParam = null;
            sParam = GetGraph();
            //get S11 Info, S21 is the same operation as S11:
            MWNumericArray S11 = (MWNumericArray)sParam.GetField("S11");
            double[,] S11_Real = (double[,])S11.ToArray(MWArrayComponent.Real);
            double[] s11_Real = ranktransfer(S11_Real);
            double[,] S11_Img = (double[,])S11.ToArray(MWArrayComponent.Imaginary);
            double[] s11_Img = ranktransfer(S11_Img);
            int n = s11_Real.Length;
            double[] s11 = new double[n];
            for (int i = 0; i < n; i++)
            {
                s11[i] = 20 * Math.Log10(Math.Abs(Math.Sqrt(s11_Real[i] * s11_Real[i] + s11_Img[i] * s11_Img[i])));
            }
            return s11;
        }

        public static double[] GetS11P()
        {
            MWStructArray sParam = null;
            sParam = GetGraph();
            //get S11 Info, S21 is the same operation as S11:
            MWNumericArray S11 = (MWNumericArray)sParam.GetField("S11");
            double[,] S11_Real = (double[,])S11.ToArray(MWArrayComponent.Real);
            double[] s11_Real = ranktransfer(S11_Real);
            double[,] S11_Img = (double[,])S11.ToArray(MWArrayComponent.Imaginary);
            double[] s11_Img = ranktransfer(S11_Img);
            int n = s11_Real.Length;
            double[] s11 = new double[n];
            for (int i = 0; i < n; i++)
                s11[i] = Math.Atan2(s11_Img[i], s11_Real[i]) * 180/Math.PI;
            return s11;
        }

        public static double[] GetS21()
        {
            MWStructArray sParam = null;
            sParam = GetGraph();
            //get S11 Info, S21 is the same operation as S11:
            MWNumericArray S21 = (MWNumericArray)sParam.GetField("S21");
            double[,] S21_Real = (double[,])S21.ToArray(MWArrayComponent.Real);
            double[] s21_Real = ranktransfer(S21_Real);
            double[,] S21_Img = (double[,])S21.ToArray(MWArrayComponent.Imaginary);
            double[] s21_Img = ranktransfer(S21_Img);
            int n = s21_Real.Length;
            double[] s21 = new double[n];
            for (int i = 0; i < n; i++)
                s21[i] = 20 * Math.Log10(Math.Abs(Math.Sqrt(s21_Real[i] * s21_Real[i] + s21_Img[i] * s21_Img[i])));
            return s21;
        }

        public static double[] GetS21P()
        {
            MWStructArray sParam = null;
            sParam = GetGraph();
            //get S11 Info, S21 is the same operation as S11:
            MWNumericArray S21 = (MWNumericArray)sParam.GetField("S21");
            double[,] S21_Real = (double[,])S21.ToArray(MWArrayComponent.Real);
            double[] s21_Real = ranktransfer(S21_Real);
            double[,] S21_Img = (double[,])S21.ToArray(MWArrayComponent.Imaginary);
            double[] s21_Img = ranktransfer(S21_Img);
            int n = s21_Real.Length;
            double[] s21 = new double[n];
            for (int i = 0; i < n; i++)
                s21[i] = Math.Atan2(s21_Img[i], s21_Real[i]) * 180/Math.PI;
            return s21;
        }

        public static double[] GetDelay()
        {
            MWStructArray sParam = null;
            sParam = GetGraph();            
            //Get Delay Info:
            MWNumericArray Delay = (MWNumericArray)sParam.GetField("Delay");
            double[,] nativeDelay = (double[,])Delay.ToArray();
            double[] delay = ranktransfer(nativeDelay);
            return delay;
        }

        private static MWStructArray GetGraph()
        {
            double highF = fp.HighF;
            double lowF = fp.LowF;
            MWNumericArray startFeq = null;
            MWNumericArray stopFeq = null;
            MWNumericArray Qdata = null;

            startFeq = fp.StartF;
            stopFeq = fp.StopF;
            Qdata = (MWNumericArray)(fp.Q);

            MWStructArray SParam = null;
            Filter demoFilter = new Filter();
            MWNumericArray feq = new MWNumericArray(lineSpace(lowF, highF, 1001));
            SParam = (MWStructArray)demoFilter.PassFilterPlot1(feq, (MWNumericArray)fp.CpMatrix, startFeq, stopFeq, Qdata);

            return SParam;
        }
                
        public static double[] lineSpace(double low, double high, int nop)
        {
            double[] feqArray = new double[nop];
            double step = (high - low) / (nop - 1);
            for (int i = 0; i < nop; i++)
            {
                feqArray[i] = low + i * step;
            }
            return feqArray;
        }

        private static double[] ranktransfer(double[,] rank2)
        {
            double[] rank1 = new double[rank2.GetLength(1)];
            for (int i = 0; i < rank2.GetLength(1); i++)
                rank1[i] = rank2[0, i];
            return rank1;
        }

        /// 自動縮放控件
        /// </summary>
        /// <param name="frm"></param>
        public static void AutoScale(Form frm)
        {
            frm.Tag = frm.Width.ToString() + "," + frm.Height.ToString();
            frm.SizeChanged += new EventHandler(frm_SizeChanged);
        }


        static void frm_SizeChanged(object sender, EventArgs e)
        {
            string[] tmp = ((Form)sender).Tag.ToString().Split(',');
            float width = (float)((Form)sender).Width / (float)Convert.ToInt16(tmp[0]);
            float heigth = (float)((Form)sender).Height / (float)Convert.ToInt16(tmp[1]);

            ((Form)sender).Tag = ((Form)sender).Width.ToString() + "," + ((Form)sender).Height;

            foreach (Control control in ((Form)sender).Controls)
            {
                control.Scale(new SizeF(width, heigth));
            }
        }

        public static bool Writes2p(string path)
        {
            double highF = fp.HighF;
            double lowF = fp.LowF;
            MWStructArray SParam = null;
            SParam = GetGraph();
            MWNumericArray S11 = (MWNumericArray)SParam.GetField("S11");
            MWNumericArray S21 = (MWNumericArray)SParam.GetField("S21");
            MWCharArray spath = new MWCharArray(path);
            MWNumericArray feq = new MWNumericArray(lineSpace(lowF, highF, 1001));
            Filter demoFilter = new Filter();
            MWLogicalArray writeOK = (MWLogicalArray)demoFilter.calS2pData(spath, feq, S11, S21);
            if (writeOK.ToString().Trim() == "1")
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}